package com.zdb.n1.service.impl;

import com.zdb.n1.entity.ExerciseRecord;
import com.zdb.n1.entity.ExerciseType;
import com.zdb.n1.entity.User;
import com.zdb.n1.payload.response.MessageResponse;
import com.zdb.n1.repository.ExerciseRecordRepository;
import com.zdb.n1.service.ExerciseRecordService;
import com.zdb.n1.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Calendar;
import java.util.stream.Collectors;

@Service
public class ExerciseRecordServiceImpl implements ExerciseRecordService {

    @Autowired
    private ExerciseRecordRepository exerciseRecordRepository;

    @Autowired
    private UserService userService;

    @Override
    @Transactional
    public ExerciseRecord saveExerciseRecord(ExerciseRecord exerciseRecord) {
        User currentUser = userService.getCurrentUser();
        exerciseRecord.setUser(currentUser);
        
        // 确保记录时间已设置
        if (exerciseRecord.getStartTime() == null) {
            exerciseRecord.setStartTime(new Date());
        } else {
            // 处理时间格式，去除毫秒部分
            Date startDate = exerciseRecord.getStartTime();
            Calendar calStart = Calendar.getInstance();
            calStart.setTime(startDate);
            calStart.set(Calendar.MILLISECOND, 0);
            exerciseRecord.setStartTime(calStart.getTime());
        }
        
        if (exerciseRecord.getEndTime() != null) {
            // 处理结束时间格式，去除毫秒部分
            Date endDate = exerciseRecord.getEndTime();
            Calendar calEnd = Calendar.getInstance();
            calEnd.setTime(endDate);
            calEnd.set(Calendar.MILLISECOND, 0);
            exerciseRecord.setEndTime(calEnd.getTime());
        }
        
        return exerciseRecordRepository.save(exerciseRecord);
    }

    @Override
    public ExerciseRecord getExerciseRecordById(Long id) {
        return exerciseRecordRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("未找到运动记录"));
    }

    @Override
    public List<ExerciseRecord> getAllExerciseRecordsForCurrentUser() {
        User currentUser = userService.getCurrentUser();
        List<ExerciseRecord> records = exerciseRecordRepository.findByUserOrderByStartTimeDesc(currentUser);
        
        // 转换为没有懒加载关联的数据对象
        return records.stream().map(record -> {
            ExerciseRecord dto = new ExerciseRecord();
            dto.setId(record.getId());
            dto.setStartTime(record.getStartTime());
            dto.setEndTime(record.getEndTime());
            dto.setDurationMinutes(record.getDurationMinutes());
            dto.setCaloriesBurned(record.getCaloriesBurned());
            dto.setNotes(record.getNotes());
            dto.setIntensity(record.getIntensity());
            dto.setLocation(record.getLocation());
            
            // 只保留必要的exerciseType信息
            if (record.getExerciseType() != null) {
                ExerciseType typeDto = new ExerciseType();
                typeDto.setId(record.getExerciseType().getId());
                typeDto.setName(record.getExerciseType().getName());
                typeDto.setCaloriesPerMinute(record.getExerciseType().getCaloriesPerMinute());
                typeDto.setCategory(record.getExerciseType().getCategory());
                dto.setExerciseType(typeDto);
            }
            
            // 不设置user，避免懒加载问题
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public Page<ExerciseRecord> getExerciseRecordsForCurrentUserPaged(Pageable pageable) {
        User currentUser = userService.getCurrentUser();
        return exerciseRecordRepository.findByUserOrderByStartTimeDesc(currentUser, pageable);
    }

    @Override
    public List<ExerciseRecord> getExerciseRecordsByDateRange(Date startDate, Date endDate) {
        User currentUser = userService.getCurrentUser();
        
        // 调整时间范围，确保包含整个开始日期和结束日期
        Calendar calStart = Calendar.getInstance();
        calStart.setTime(startDate);
        calStart.set(Calendar.HOUR_OF_DAY, 0);
        calStart.set(Calendar.MINUTE, 0);
        calStart.set(Calendar.SECOND, 0);
        calStart.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calStart.getTime();
        
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(endDate);
        calEnd.set(Calendar.HOUR_OF_DAY, 23);
        calEnd.set(Calendar.MINUTE, 59);
        calEnd.set(Calendar.SECOND, 59);
        calEnd.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calEnd.getTime();
        
        List<ExerciseRecord> records = exerciseRecordRepository.findByUserAndStartTimeBetweenOrderByStartTimeDesc(
                currentUser, startOfDay, endOfDay);
        
        // 转换为没有懒加载关联的数据对象
        return records.stream().map(record -> {
            ExerciseRecord dto = new ExerciseRecord();
            dto.setId(record.getId());
            dto.setStartTime(record.getStartTime());
            dto.setEndTime(record.getEndTime());
            dto.setDurationMinutes(record.getDurationMinutes());
            dto.setCaloriesBurned(record.getCaloriesBurned());
            dto.setNotes(record.getNotes());
            dto.setIntensity(record.getIntensity());
            dto.setLocation(record.getLocation());
            
            // 只保留必要的exerciseType信息
            if (record.getExerciseType() != null) {
                ExerciseType typeDto = new ExerciseType();
                typeDto.setId(record.getExerciseType().getId());
                typeDto.setName(record.getExerciseType().getName());
                typeDto.setCaloriesPerMinute(record.getExerciseType().getCaloriesPerMinute());
                typeDto.setCategory(record.getExerciseType().getCategory());
                dto.setExerciseType(typeDto);
            }
            
            // 不设置user，避免懒加载问题
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public List<ExerciseRecord> getExerciseRecordsByType(ExerciseType exerciseType) {
        User currentUser = userService.getCurrentUser();
        List<ExerciseRecord> records = exerciseRecordRepository.findByUserAndExerciseTypeOrderByStartTimeDesc(
                currentUser, exerciseType);
        
        // 转换为没有懒加载关联的数据对象
        return records.stream().map(record -> {
            ExerciseRecord dto = new ExerciseRecord();
            dto.setId(record.getId());
            dto.setStartTime(record.getStartTime());
            dto.setEndTime(record.getEndTime());
            dto.setDurationMinutes(record.getDurationMinutes());
            dto.setCaloriesBurned(record.getCaloriesBurned());
            dto.setNotes(record.getNotes());
            dto.setIntensity(record.getIntensity());
            dto.setLocation(record.getLocation());
            
            // 只保留必要的exerciseType信息
            if (record.getExerciseType() != null) {
                ExerciseType typeDto = new ExerciseType();
                typeDto.setId(record.getExerciseType().getId());
                typeDto.setName(record.getExerciseType().getName());
                typeDto.setCaloriesPerMinute(record.getExerciseType().getCaloriesPerMinute());
                typeDto.setCategory(record.getExerciseType().getCategory());
                dto.setExerciseType(typeDto);
            }
            
            // 不设置user，避免懒加载问题
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public Integer getTotalDurationForCurrentUser() {
        User currentUser = userService.getCurrentUser();
        Integer totalDuration = exerciseRecordRepository.getTotalDurationByUser(currentUser);
        return totalDuration != null ? totalDuration : 0;
    }

    @Override
    public Integer getTotalDurationForCurrentUserByDateRange(Date startDate, Date endDate) {
        User currentUser = userService.getCurrentUser();
        
        // 调整时间范围，确保包含整个开始日期和结束日期
        Calendar calStart = Calendar.getInstance();
        calStart.setTime(startDate);
        calStart.set(Calendar.HOUR_OF_DAY, 0);
        calStart.set(Calendar.MINUTE, 0);
        calStart.set(Calendar.SECOND, 0);
        calStart.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calStart.getTime();
        
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(endDate);
        calEnd.set(Calendar.HOUR_OF_DAY, 23);
        calEnd.set(Calendar.MINUTE, 59);
        calEnd.set(Calendar.SECOND, 59);
        calEnd.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calEnd.getTime();
        
        Integer totalDuration = exerciseRecordRepository.getTotalDurationByUserAndDateRange(
                currentUser, startOfDay, endOfDay);
        return totalDuration != null ? totalDuration : 0;
    }

    @Override
    public Double getTotalCaloriesForCurrentUser() {
        User currentUser = userService.getCurrentUser();
        Double totalCalories = exerciseRecordRepository.getTotalCaloriesByUser(currentUser);
        return totalCalories != null ? totalCalories : 0.0;
    }

    @Override
    public Double getTotalCaloriesForCurrentUserByDateRange(Date startDate, Date endDate) {
        User currentUser = userService.getCurrentUser();
        
        // 调整时间范围，确保包含整个开始日期和结束日期
        Calendar calStart = Calendar.getInstance();
        calStart.setTime(startDate);
        calStart.set(Calendar.HOUR_OF_DAY, 0);
        calStart.set(Calendar.MINUTE, 0);
        calStart.set(Calendar.SECOND, 0);
        calStart.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calStart.getTime();
        
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(endDate);
        calEnd.set(Calendar.HOUR_OF_DAY, 23);
        calEnd.set(Calendar.MINUTE, 59);
        calEnd.set(Calendar.SECOND, 59);
        calEnd.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calEnd.getTime();
        
        Double totalCalories = exerciseRecordRepository.getTotalCaloriesByUserAndDateRange(
                currentUser, startOfDay, endOfDay);
        return totalCalories != null ? totalCalories : 0.0;
    }

    @Override
    public Map<ExerciseType, Long> getExerciseTypeDistributionForCurrentUser() {
        User currentUser = userService.getCurrentUser();
        List<Object[]> distribution = exerciseRecordRepository.getExerciseTypeDistribution(currentUser);
        
        Map<ExerciseType, Long> result = new HashMap<>();
        for (Object[] entry : distribution) {
            ExerciseType type = (ExerciseType) entry[0];
            Long count = (Long) entry[1];
            result.put(type, count);
        }
        
        return result;
    }

    @Override
    @Transactional
    public MessageResponse deleteExerciseRecord(Long id) {
        ExerciseRecord record = exerciseRecordRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("未找到运动记录"));
        
        User currentUser = userService.getCurrentUser();
        if (!record.getUser().getId().equals(currentUser.getId())) {
            return MessageResponse.error("无权删除此记录");
        }
        
        exerciseRecordRepository.delete(record);
        return MessageResponse.success("记录删除成功");
    }
}